<template>
	<div class='dept-maintain-container'>
		<div class='left'>
			<n-input v-model:value='treeConfig.pattern' type='text' clearable/>
			<br/>
			<n-tree ref='treeRef' v-bind='treeConfig'/>
		</div>
		<div class='right'>
			<div class='info'>
				<n-form ref='formRef' v-bind='formConfig' :model='currentDept.currentNode'>
					<n-grid v-if='currentDept.currentNode'
							:cols='24' x-gap='15' y-gap='15'>
						<n-form-item-gi :span='24' label='上级部门编码' path='parentDeptCode'>
							{{ currentDept.currentNode.parentDeptCode }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='部门编码' path='deptCode'>
							{{ currentDept.currentNode.deptCode }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='部门简称' path='deptAbbName'>
							{{ currentDept.currentNode.deptAbbName }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='部门名称' path='deptName'>
							{{ currentDept.currentNode.deptName }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='部门电话' path='deptName'>
							{{ currentDept.currentNode.deptPhone }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='部门地址' path='deptAddress'>
							{{ currentDept.currentNode.deptAddress }}
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='是否禁用' path='disabled'>
							<template v-if='true === currentDept.currentNode.disabled'>
								禁用
							</template>
							<template v-else-if='false === currentDept.currentNode.disabled'>
								启用
							</template>
						</n-form-item-gi>
						<n-form-item-gi :span='24' label='排序' path='sort'>
							{{ currentDept.currentNode.sort }}
						</n-form-item-gi>
					</n-grid>
				</n-form>
			</div>
		</div>
		<n-dropdown v-bind='contextMenuConfig' :on-clickoutside='onClickOutSide' @select='handleSelect'/>
	</div>
	<AddModal ref='addModalRef' v-bind='addModalConfig'/>
	<EditModal ref='editModalRef' v-bind='editModalConfig'/>
</template>
<script lang='ts' setup>
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
import axios from '@/config/axios/index.ts';
import type { JsonResultProps } from '#/JsonResult.d.ts';
import { VxeUI } from '@/config/vxe/index.ts';
import { DropdownProps, FormProps, NForm, NTree, TreeOption, TreeProps } from 'naive-ui';
import type { DeptMaintainInfoProps } from '#/src/components/page/systemManager/deptMaintain/DeptMaintainProps.d.ts';
import type { TreeDropInfo } from 'naive-ui/es/tree/src/interface.d.ts';
const SvgIcon = defineAsyncComponent(() => import('@/components/customComponents/icon/SvgIcon.vue'));
const AddModal = defineAsyncComponent(() => import('./addModal.vue'));
const EditModal = defineAsyncComponent(() => import('./editModal.vue'));
const props = defineProps({
	params : {
		type    : Object,
		require : false,
		default : null
	}
});
// 树
const treeRef = ref<InstanceType<typeof NTree>>();
const treeConfig = reactive<TreeProps>({
	showLine            : true,
	draggable           : true,
	animated            : true,
	accordion           : true,
	blockLine           : true,
	selectable          : true,
	virtualScroll       : true,
	expandOnClick       : false,
	showIrrelevantNodes : false,
	keyField            : 'deptCode',
	labelField          : 'deptAbbName',
	disabledField       : 'disabled',
	childrenField       : 'children',
	pattern             : '',
	selectedKeys        : [],
	data                : [],
	nodeProps           : ({ option }: { option: TreeOption | DeptMaintainInfoProps }) => {
		return {
			onClick() {
				currentDept.currentNode = option as DeptMaintainInfoProps;
			},
			onContextmenu(e: MouseEvent): void {
				e.preventDefault();
				e.stopPropagation();
				e.stopImmediatePropagation();
				currentDept.currentNode = option as DeptMaintainInfoProps;
				contextMenuConfig.show = true;
				contextMenuConfig.x = e.clientX;
				contextMenuConfig.y = e.clientY;
			}
		};
	},
	onLoad              : (node: TreeOption) => initTree(node),
	onDrop              : (e: TreeDropInfo) => dragEvent(e)
});
// 表单
const formRef = ref<InstanceType<typeof NForm>>();
const formConfig = reactive<FormProps>({
	size           : 'large',
	showLabel      : true,
	labelWidth     : 'auto',
	labelAlign     : 'left',
	labelPlacement : 'left',
	showFeedback   : true,
	// showRequireMark : true
	requireMarkPlacement : 'left'
});
// 当前选择项
const currentDept = reactive({
	currentNode : {} as DeptMaintainInfoProps
});
const renderIcon = (iconType: string, iconClass: string): any => {
	return () => {
		// @ts-ignore
		return h(SvgIcon, {
			'icon-type'  : iconType,
			'icon-class' : iconClass
		});
	};
};
const contextMenuConfig = reactive<DropdownProps>({
	show      : false,
	animated  : true,
	size      : 'large',
	placement : 'bottom-start',
	trigger   : 'manual',
	x         : 0,
	y         : 0,
	options   : [
		{ label : '新增同级部门', key : 'addBrotherDept', icon : renderIcon('iconfont5', 'iconfont5-Add') },
		{ label : '新增子级部门', key : 'addSubordinateDept', icon : renderIcon('iconfont5', 'iconfont5-Add') },
		{ label : '修改部门', key : 'editDept', icon : renderIcon('iconfont5', 'iconfont5-Close') },
		{ label : '删除部门', key : 'removeDept', icon : renderIcon('iconfont5', 'iconfont5-Close') }
	]
});
// 模态框
const addModalRef = ref<InstanceType<typeof AddModal>>();
const editModalRef = ref<InstanceType<typeof EditModal>>();
const addModalConfig = reactive({
	reLoad : () => initTree(null)
});
const editModalConfig = reactive({
	reLoad : () => initTree(null)
});
onMounted(() => {
	initTree(null);
});
const initTree = async (node: TreeOption | null) => {
	const data = {
		tenantCode : null as string | number | null,
		deptCode   : null as any
	};
	const tenantCode = sessionStorage.getItem('loginTenantCode');
	if (tenantCode) {
		data.tenantCode = tenantCode;
	}
	if (node) {
		data.deptCode = node.deptCode;
	} else {
		data.deptCode = '0';
	}
	return new Promise<void>((resolve, reject) => {
		axios<any, JsonResultProps<any>, any>({
			method : 'POST',
			url    : '/department/asyncTreeList',
			data   : data
		}).then((jsonResult: JsonResultProps<any>) => {
			if (jsonResult['status']) {
				if (node) {
					// 有数据的时候才加载
					if (jsonResult['data']) {
						node.children = jsonResult['data'];
					}
				} else {
					treeConfig['data'] = jsonResult['data'];
				}
				resolve();
			} else {
				reject();
				VxeUI.modal.message({
					content : jsonResult['msg'],
					status  : 'warning',
					id      : 'failedMessage'
				});
			}
		}).catch((error: unknown) => {
			reject();
			console.error(error);
			VxeUI.modal.message({
				content : '系统异常,请稍后再试',
				status  : 'error',
				id      : 'errorMessage'
			});
		});
	});
};
const dragEvent = async (e: TreeDropInfo) => {
	// 清空右侧的当前节点信息
	currentDept.currentNode = {} as DeptMaintainInfoProps;
	const node = e.node;
	const dropPosition = e.dropPosition;
	const dragNode = e.dragNode;
	console.log('e:', e);
	axios<any, JsonResultProps<any>, any>({
		method : 'PATCH',
		url    : `/department/drag/${dragNode.tenantCode}/${dragNode.deptCode}`,
		data   : {
			dragNode     : dragNode,
			dropPosition : dropPosition,
			node         : node
		}
	}).then((jsonResult: JsonResultProps<any>) => {
		if (jsonResult['status']) {
			// 提示用户
			VxeUI.modal.message({
				content : jsonResult['msg'],
				status  : 'success',
				id      : 'successMessage'
			});
			initTree(null);
		} else {
			VxeUI.modal.message({
				content : jsonResult['msg'],
				status  : 'warning',
				id      : 'failedMessage'
			});
		}
	}).catch((error: unknown) => {
		console.error(error);
		VxeUI.modal.message({
			content : '系统异常,请稍后再试',
			status  : 'error',
			id      : 'errorMessage'
		});
	});
};
const onClickOutSide = (event: MouseEvent) => {
	contextMenuConfig.show = false;
};
const handleSelect = (key: string | number) => {
	switch (key) {
		case 'addSubordinateDept':
			addSubordinateDept(currentDept.currentNode);
			break;
		case 'addBrotherDept':
			addBrotherDept(currentDept.currentNode);
			break;
		case 'editDept':
			editDept(currentDept.currentNode);
			break;
		case 'removeDept':
			removeDept(currentDept.currentNode);
			break;
	}
};
const addSubordinateDept = async (row: DeptMaintainInfoProps) => {
	addModalRef.value?.showModal('subordinate', row);
	contextMenuConfig.show = false;
};
const addBrotherDept = async (row: DeptMaintainInfoProps) => {
	addModalRef.value?.showModal('brother', row);
	contextMenuConfig.show = false;
};
const editDept = async (row: DeptMaintainInfoProps) => {
	editModalRef.value?.showModal(row);
	contextMenuConfig.show = false;
};
const removeDept = async (row: DeptMaintainInfoProps) => {
	VxeUI.modal.confirm({
		content : `确定要删除 ${row.deptAbbName} 部门吗?\n级联的下级部门也将被删除!`,
		title   : '你确定要删除吗?',
		id      : 'isRemoveDeptUnique'
	}).then((type: unknown) => {
		if ('confirm' === type) {
			axios<any, JsonResultProps<any>, any>({
				method : 'DELETE',
				url    : `/department/remove/${row.tenantCode}/${row.deptCode}`
			}).then((jsonResult: JsonResultProps<any>) => {
				if (jsonResult['status']) {
					// 提示用户
					VxeUI.modal.message({
						content : jsonResult['msg'],
						status  : 'success',
						id      : 'successMessage'
					});
					initTree(null);
				} else {
					VxeUI.modal.message({
						content : jsonResult['msg'],
						status  : 'warning',
						id      : 'failedMessage'
					});
				}
			}).catch((error: unknown) => {
				console.error(error);
				VxeUI.modal.message({
					content : '系统异常,请稍后再试',
					status  : 'error',
					id      : 'errorMessage'
				});
			});
		}
	});
	contextMenuConfig.show = false;
};
</script>
<style lang='scss' scoped>
.dept-maintain-container{
	box-sizing    :border-box;
	margin        :0;
	padding       :1%;
	border        :0;
	height        :100%;
	width         :100%;
	display       :flex;
	flex-flow     :row nowrap;
	place-content :center flex-start;
	place-items   :center center;
	place-self    :center center;
	.left{
		box-sizing    :border-box;
		margin        :0;
		padding       :1%;
		border        :0;
		height        :100%;
		width         :50%;
		display       :flex;
		flex-flow     :column nowrap;
		place-content :center flex-start;
		place-items   :center center;
		place-self    :center center;
	}
	.right{
		box-sizing :border-box;
		margin     :0;
		padding    :1%;
		border     :0;
		height     :100%;
		width      :50%;
		.info{
			box-sizing    :border-box;
			margin        :0;
			padding       :0;
			border        :0;
			height        :100%;
			width         :100%;
			overflow      :auto;
			display       :flex;
			flex-flow     :column nowrap;
			place-content :center flex-start;
			place-items   :center center;
			place-self    :center center;
		}
		html[data-theme='light'] &{
			background-color :rgba(0, 0, 0, .05);
		}
		html[data-theme='dark'] &{
			background-color :rgba(0, 0, 0, .8);
		}
	}
}
</style>